From 1160bd2fd81f17d9a8747023b2f6c49c183f286e Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 26 Jun 2012 16:23:47 +0100 Subject: [PATCH] arm: enable interrupts while handling traps For most traps we can do this as soon as we have saved the necessary state. For IRQs and FIQs we must wait until we have acked the interrupt with the GIC. Signed-off-by: Ian Campbell Acked-by: Stefano Stabellini Committed-by: Ian Campbell --- xen/arch/arm/entry.S | 17 ++++++++++++++--- xen/arch/arm/gic.c | 2 ++ xen/arch/arm/traps.c | 1 - 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/entry.S b/xen/arch/arm/entry.S index 7a22e2d9e9..5bc39063f9 100644 --- a/xen/arch/arm/entry.S +++ b/xen/arch/arm/entry.S @@ -44,6 +44,17 @@ save_guest_regs: #define DEFINE_TRAP_ENTRY(trap) \ ALIGN; \ +trap_##trap: \ + SAVE_ALL; \ + cpsie i; /* local_irq_enable */ \ + adr lr, return_from_trap; \ + mov r0, sp; \ + mov r11, sp; \ + bic sp, #7; /* Align the stack pointer (noop on guest trap) */ \ + b do_trap_##trap + +#define DEFINE_TRAP_ENTRY_NOIRQ(trap) \ + ALIGN; \ trap_##trap: \ SAVE_ALL; \ adr lr, return_from_trap; \ @@ -69,8 +80,8 @@ DEFINE_TRAP_ENTRY(supervisor_call) DEFINE_TRAP_ENTRY(prefetch_abort) DEFINE_TRAP_ENTRY(data_abort) DEFINE_TRAP_ENTRY(hypervisor) -DEFINE_TRAP_ENTRY(irq) -DEFINE_TRAP_ENTRY(fiq) +DEFINE_TRAP_ENTRY_NOIRQ(irq) +DEFINE_TRAP_ENTRY_NOIRQ(fiq) return_from_trap: mov sp, r11 @@ -83,7 +94,7 @@ ENTRY(return_to_new_vcpu) ENTRY(return_to_guest) mov r11, sp bic sp, #7 /* Align the stack pointer */ - bl leave_hypervisor_tail + bl leave_hypervisor_tail /* Disables interrupts on return */ mov sp, r11 RESTORE_ONE_BANKED(SP_usr) /* LR_usr is the same physical register as lr and is restored below */ diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index cc9d37b3d3..1a2b95f248 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -509,6 +509,8 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq) uint32_t intack = GICC[GICC_IAR]; unsigned int irq = intack & GICC_IA_IRQ; + local_irq_enable(); + if ( irq == 1023 ) /* Spurious interrupt */ return; diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index abc26a32ec..5ed754f9ed 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -412,7 +412,6 @@ static void do_debug_trap(struct cpu_user_regs *regs, unsigned int code) static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss) { arm_hypercall_t *call = NULL; - local_irq_enable(); if ( iss != XEN_HYPERCALL_TAG ) { -- 2.30.2